package Gui;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.KeyEventDispatcher;
import java.awt.KeyboardFocusManager;
import java.awt.SystemColor;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.AffineTransform;
import java.io.File;
import java.io.IOException;

import javax.swing.BorderFactory;
import javax.swing.ButtonGroup;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.ScrollPaneConstants;
import javax.swing.SwingConstants;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.BevelBorder;
import javax.swing.border.TitledBorder;

import lejos.robotics.navigation.Pose;
import simulator.labyrinth.Labyrinth;
import simulator.robot.Simulator;
import Program.LabyrinthParser;
import Program.SpeedListener;
import Robot.RobotControl;
import Robot.RobotDirection;
import Robot.SensorColour;

public class MainGui implements SpeedListener {
	
	private static final Color GREEN = new Color(34, 139, 34);

	private static final double ROTATE_VALUE = 90;
	private static final double TRAVEL_VALUE = 40;

	private final RobotControl robotControl;
	private final DrivePolygonDialog polygonDialog;
	
	private JFrame frame;
	private JPanel panel;
	private JLabel lblRobotDirectionEdit;
	private JLabel lblStatus;
	private JLabel lblSonarAngleEdit;
	private JLabel lblTouch_2Edit;
	private JLabel lblTouch_1Edit;
	private JLabel lblLightSensorEdit;
	private JLabel lblSonarEdit;
	private KeyboardFocusManager manager;
	private final RadioButtonListener radioButtonListener = new RadioButtonListener();
	private JTextField speed;
	private JTextField rotate;

	private JTextArea textAreaActie;
	private JLabel lblPilot;
	private JTextArea textAreaDebug;
	private JLabel lblLightSensorColour;
	private JButton sonar_up;
	private JButton sonar_left;
	private JButton sonar_right;
	private JPanel remoteControl;
	private JButton btnTravel;
	private JButton btnRotate;
	private JButton btnTravel20;
	private JButton btnTravel20Back;
	private JButton btnRotate90;
	private JButton btnRotateMin90;
	private JButton btnRobotDown;
	private JButton btnRobotRight;
	private JButton btnRobotUp;
	private JButton btnRobotLeft;
	private KeyEventDispatcher keyDispatcher;
	private JLabel lblRobotOrientationEdit;
	private JLabel lblRobotPositionEdit;
	private JButton btnDrivePolygon;

	private JButton btnRemoteControl;

	private JButton btnChangePilot;

	private JButton discoverLabyrinth;

	/**
	 * Create the application.
	 */
	public MainGui(RobotControl control) {
		robotControl = control;
		polygonDialog = new DrivePolygonDialog(robotControl, this.frame);
		keyDispatcher = new KeyDispatcher(control);
		setLookAndFeel();
		initialize();
		setKeyBindings();
		this.frame.setVisible(true);
	}
	
	private void setLookAndFeel()
	{
		try {
			UIManager.setLookAndFeel(
			        UIManager.getSystemLookAndFeelClassName());
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (UnsupportedLookAndFeelException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	private void setKeyBindings()
	{
		//Hijack the keyboard manager
		manager = KeyboardFocusManager.getCurrentKeyboardFocusManager();
		manager.addKeyEventDispatcher(keyDispatcher );
	}

	/**
	 * Initialize the contents of the frame.
	 */
	private void initialize() {
		frame = new JFrame();
		frame.setBounds(100, 100, 872, 501);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.getContentPane().setLayout(new BorderLayout(0, 0));
		
		JLabel titleLabel = new JLabel("Robot Control - Indigo");
		titleLabel.setFont(new Font("Tahoma", Font.BOLD, 20));
		titleLabel.setHorizontalAlignment(SwingConstants.CENTER);
		frame.getContentPane().add(titleLabel, BorderLayout.NORTH);
		
		panel = new JPanel();
		frame.getContentPane().add(panel, BorderLayout.CENTER);
		panel.setLayout(null);
		
		JPanel infoPanel = new JPanel();
		infoPanel.setBorder(new TitledBorder(null, "Sensor info", TitledBorder.LEADING, TitledBorder.TOP, null, null));
		infoPanel.setBounds(0, 3, 170, 267);
		panel.add(infoPanel);
		
		remoteControl = new JPanel();
		remoteControl.setBounds(180, 3, 287, 267);
		remoteControl.setLayout(null);
//		panel.add(remoteControl);	//TODO uitcommentarieren om te editen
		
		JLabel lblSonar = new JLabel("Sonar:");
		lblSonar.setBounds(10, 25, 46, 20);
		lblSonar.setFont(new Font("Tahoma", Font.PLAIN, 12));
		
		lblSonarEdit = new JLabel("0.0");
		lblSonarEdit.setBounds(115, 25, 46, 20);
		lblSonarEdit.setFont(new Font("Tahoma", Font.PLAIN, 12));
		lblSonarEdit.setForeground(GREEN);
		
		JLabel lblLightSensor = new JLabel("Light sensor:");
		lblLightSensor.setBounds(10, 65, 75, 20);
		lblLightSensor.setFont(new Font("Tahoma", Font.PLAIN, 12));
		
		lblLightSensorEdit = new JLabel("0.0");
		lblLightSensorEdit.setBounds(115, 65, 46, 20);
		lblLightSensorEdit.setFont(new Font("Tahoma", Font.PLAIN, 12));
		
		lblLightSensorColour = new JLabel("None");
		lblLightSensorColour.setBounds(115, 85, 46, 14);
		lblLightSensorColour.setFont(new Font("Tahoma", Font.PLAIN, 12));
		
		JLabel lblTouch = new JLabel("Touch 1: ");
		lblTouch.setBounds(10, 105, 60, 20);
		lblTouch.setFont(new Font("Tahoma", Font.PLAIN, 12));
		
		JLabel lblTouch_1 = new JLabel("Touch 2: ");
		lblTouch_1.setBounds(10, 125, 54, 20);
		lblTouch_1.setFont(new Font("Tahoma", Font.PLAIN, 12));
		
		lblTouch_1Edit = new JLabel("No");
		lblTouch_1Edit.setBounds(115, 105, 46, 20);
		lblTouch_1Edit.setFont(new Font("Tahoma", Font.PLAIN, 12));
		
		lblTouch_2Edit = new JLabel("No");
		lblTouch_2Edit.setBounds(115, 125, 46, 20);
		lblTouch_2Edit.setFont(new Font("Tahoma", Font.PLAIN, 12));
		
		JLabel lblRobotDirection = new JLabel("Robot direction:");
		lblRobotDirection.setFont(new Font("Tahoma", Font.PLAIN, 12));
		lblRobotDirection.setBounds(10, 145, 93, 14);
		
		lblRobotDirectionEdit = new JLabel("None");
		lblRobotDirectionEdit.setBounds(115, 145, 46, 14);
		lblRobotDirectionEdit.setFont(new Font("Tahoma", Font.PLAIN, 12));
		
		JLabel lblSonarAngle = new JLabel("Sonar angle:");
		lblSonarAngle.setBounds(10, 45, 75, 20);
		lblSonarAngle.setFont(new Font("Tahoma", Font.PLAIN, 12));
		
		lblSonarAngleEdit = new JLabel("0.0");
		lblSonarAngleEdit.setBounds(115, 45, 46, 20);
		lblSonarAngleEdit.setFont(new Font("Tahoma", Font.PLAIN, 12));
		infoPanel.setLayout(null);
		infoPanel.add(lblSonar);
		infoPanel.add(lblSonarEdit);
		infoPanel.add(lblLightSensor);
		infoPanel.add(lblLightSensorEdit);
		infoPanel.add(lblLightSensorColour);
		infoPanel.add(lblTouch);
		infoPanel.add(lblTouch_1);
		infoPanel.add(lblTouch_1Edit);
		infoPanel.add(lblTouch_2Edit);
		infoPanel.add(lblRobotDirection);
		infoPanel.add(lblRobotDirectionEdit);
		infoPanel.add(lblSonarAngle);
		infoPanel.add(lblSonarAngleEdit);
		
		JLabel lblRobotPosition = new JLabel("Robot position:");
		lblRobotPosition.setFont(new Font("Tahoma", Font.PLAIN, 12));
		lblRobotPosition.setBounds(10, 165, 93, 14);
		infoPanel.add(lblRobotPosition);
		
		lblRobotPositionEdit = new JLabel("None");
		lblRobotPositionEdit.setHorizontalAlignment(SwingConstants.CENTER);
		lblRobotPositionEdit.setFont(new Font("Tahoma", Font.PLAIN, 12));
		lblRobotPositionEdit.setBounds(10, 185, 138, 14);
		infoPanel.add(lblRobotPositionEdit);
		
		JLabel lblRobotOrientation = new JLabel("Robot orientation:");
		lblRobotOrientation.setFont(new Font("Tahoma", Font.PLAIN, 12));
		lblRobotOrientation.setBounds(10, 205, 100, 14);
		infoPanel.add(lblRobotOrientation);
		
		lblRobotOrientationEdit = new JLabel("None");
		lblRobotOrientationEdit.setFont(new Font("Tahoma", Font.PLAIN, 12));
		lblRobotOrientationEdit.setBounds(115, 205, 46, 14);
		infoPanel.add(lblRobotOrientationEdit);
		
		JButton btnResetPosition = new JButton("Reset Position");
		btnResetPosition.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				robotControl.setResetPosition(true);
			}
		});
		btnResetPosition.setBounds(25, 230, 113, 20);
		infoPanel.add(btnResetPosition);
		
		JPanel controlPanel = new JPanel();
		controlPanel.setBorder(new TitledBorder(null, "Control", TitledBorder.LEADING, TitledBorder.TOP, null, null));
		controlPanel.setBounds(477, 3, 191, 424);
		panel.add(controlPanel);
		controlPanel.setLayout(null);
		
		btnDrivePolygon = new JButton(new ImageIcon(
				new ImageIcon(MainGui.class.getResource("/res/polygon.png")).
				getImage().getScaledInstance(28, 28, java.awt.Image.SCALE_SMOOTH)) );
		btnDrivePolygon.setHorizontalAlignment(SwingConstants.LEFT);
		btnDrivePolygon.setToolTipText("Drive polygon");
		btnDrivePolygon.setBorder(BorderFactory.createEmptyBorder());
		btnDrivePolygon.setContentAreaFilled(false);
		btnDrivePolygon.setCursor(new Cursor(Cursor.HAND_CURSOR));
		btnDrivePolygon.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {

				polygonDialog.open();
				
			}
		});
		btnDrivePolygon.setBounds(10, 139, 29, 29);
		controlPanel.add(btnDrivePolygon);

		btnRemoteControl = new JButton(new ImageIcon(
				new ImageIcon(MainGui.class.getResource("/res/remote-control.png")).
				getImage().getScaledInstance(28, 28, java.awt.Image.SCALE_SMOOTH)) );
		btnRemoteControl.setHorizontalAlignment(SwingConstants.LEFT);
		btnRemoteControl.setToolTipText("Remote control");
		btnRemoteControl.setBorder(BorderFactory.createEmptyBorder());
		btnRemoteControl.setContentAreaFilled(false);
		btnRemoteControl.setCursor(new Cursor(Cursor.HAND_CURSOR));
		btnRemoteControl.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent event) {
				
				if (lblStatus.getText().equals("Not active")) {
					panel.add(remoteControl);
					panel.repaint();
					((KeyDispatcher)keyDispatcher).setEnabled(true);
					robotControl.setRemoteControl(true);
					lblStatus.setForeground(GREEN);
					lblStatus.setText("Active!");
				} else {
					panel.remove(remoteControl);
					panel.repaint();
					((KeyDispatcher)keyDispatcher).setEnabled(false);
					robotControl.setRemoteControl(false);
					lblStatus.setText("Not active");
					lblStatus.setForeground(Color.RED);
				}
			}
		});
		btnRemoteControl.setBounds(10, 99, 29, 29);
		controlPanel.add(btnRemoteControl);
		
		lblStatus = new JLabel("Not active");
		lblStatus.setForeground(Color.RED);
		lblStatus.setFont(new Font("Tahoma", Font.BOLD, 12));
		lblStatus.setBounds(52, 99, 75, 33);
		controlPanel.add(lblStatus);
		
		JLabel lblSpeed = new JLabel("Speed:");
		lblSpeed.setBounds(10, 54, 34, 14);
		controlPanel.add(lblSpeed);
		
		speed = new JTextField();
		speed.setBounds(49, 54, 34, 16);
		controlPanel.add(speed);
		speed.setColumns(10);
		speed.setText("" + robotControl.getTravelSpeed());
		
		JLabel lblRotate = new JLabel("Rotate:");
		lblRotate.setBounds(90, 54, 37, 14);
		controlPanel.add(lblRotate);
		
		rotate = new JTextField();
		rotate.setColumns(10);
		rotate.setBounds(132, 54, 34, 16);
		controlPanel.add(rotate);
		rotate.setText("" + robotControl.getRotateSpeed());
		
		JButton btnNewButton = new JButton("Set");
		btnNewButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				if (speed.getText() != "") {
					try {
						double travelSpeed = Double.parseDouble(speed.getText());
						if (travelSpeed > 0) {
							robotControl.setTravelSpeed(travelSpeed);
							speed.setBackground(Color.white);
						} else
							speed.setBackground(Color.red);
					} catch (NumberFormatException ex) {
						speed.setBackground(Color.red);
					}
				}
				if (rotate.getText() != "") {
					try {
						double rotateSpeed = Double.parseDouble(rotate.getText());
						if (rotateSpeed > 0) {
							robotControl.setRotateSpeed(rotateSpeed);
							rotate.setBackground(Color.white);
						} else
							rotate.setBackground(Color.red);
					} catch (NumberFormatException ex) {
						rotate.setBackground(Color.red);
					}
				}
			}
		});
		btnNewButton.setBounds(10, 73, 49, 20);
		controlPanel.add(btnNewButton);
		
		btnChangePilot = new JButton(new ImageIcon(
				new ImageIcon(MainGui.class.getResource("/res/change-pilot.png")).
				getImage().getScaledInstance(28, 28, java.awt.Image.SCALE_SMOOTH)) );
		btnChangePilot.setHorizontalAlignment(SwingConstants.LEFT);
		btnChangePilot.setToolTipText("Change pilot");
		btnChangePilot.setBorder(BorderFactory.createEmptyBorder());
		btnChangePilot.setContentAreaFilled(false);
		btnChangePilot.setCursor(new Cursor(Cursor.HAND_CURSOR));
		btnChangePilot.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				robotControl.setChangePilot(true);
			}
		});
		btnChangePilot.setBounds(10, 20, 29, 29);
		controlPanel.add(btnChangePilot);
		
		lblPilot = new JLabel("Simulator");
		lblPilot.setFont(new Font("Tahoma", Font.BOLD, 12));
		lblPilot.setBounds(52, 20, 72, 22);
		controlPanel.add(lblPilot);
		
		JPanel actiePanel = new JPanel();
		actiePanel.setBorder(new TitledBorder(null, "Actions and decisions", TitledBorder.LEADING, TitledBorder.TOP, null, null));
		actiePanel.setBounds(0, 281, 234, 146);
		panel.add(actiePanel);
		actiePanel.setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5));
		
		textAreaActie = new JTextArea();
		textAreaActie.setEditable(false);
		textAreaActie.setTabSize(5);
		textAreaActie.setFont(new Font("Monospaced", Font.PLAIN, 10));
		textAreaActie.setWrapStyleWord(true);
		textAreaActie.setLineWrap(true);
		
		JScrollPane scrollPane = new JScrollPane(textAreaActie);
		scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
		scrollPane.setToolTipText("");
		scrollPane.setBorder(new BevelBorder(BevelBorder.LOWERED, SystemColor.activeCaptionBorder, null, null, null));
		scrollPane.setPreferredSize(new Dimension(215, 110));
		actiePanel.add(scrollPane);
		scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
		
		JPanel debugPanel = new JPanel();
		debugPanel.setBorder(new TitledBorder(null, "Debug", TitledBorder.LEADING, TitledBorder.TOP, null, null));
		debugPanel.setBounds(244, 281, 234, 146);
		panel.add(debugPanel);
		debugPanel.setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5));

		textAreaDebug = new JTextArea();
		textAreaDebug.setEditable(false);
		textAreaDebug.setForeground(Color.red);
		textAreaDebug.setTabSize(5);
		textAreaDebug.setFont(new Font("Monospaced", Font.PLAIN, 10));
		textAreaDebug.setWrapStyleWord(true);
		textAreaDebug.setLineWrap(true);

		JScrollPane scrollPane_1 = new JScrollPane(textAreaDebug);
		scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
		scrollPane_1.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
		scrollPane_1.setToolTipText("");
		scrollPane_1.setPreferredSize(new Dimension(215, 110));
		scrollPane_1.setBorder(new BevelBorder(BevelBorder.LOWERED, SystemColor.activeCaptionBorder, null, null, null));
		debugPanel.add(scrollPane_1);
		
		JButton btnFindAndOrientate = new JButton("Find and orientate white line");
		btnFindAndOrientate.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				robotControl.setWhiteLine(true);
			}
		});
		btnFindAndOrientate.setBounds(10, 254, 169, 23);
		controlPanel.add(btnFindAndOrientate);
		
		JButton btnPlayTune = new JButton("Play tune");
		btnPlayTune.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				robotControl.setPlayTune(true);
			}
		});
		btnPlayTune.setBounds(10, 288, 89, 23);
		controlPanel.add(btnPlayTune);
		
		JButton btnNewButton_1 = new JButton("Open maze");
		btnNewButton_1.setBounds(10, 322, 89, 23);
		controlPanel.add(btnNewButton_1);
		
		discoverLabyrinth = new JButton(new ImageIcon(
				new ImageIcon(MainGui.class.getResource("/res/maze-icon.png")).
				getImage().getScaledInstance(32, 32, java.awt.Image.SCALE_SMOOTH)) );
		discoverLabyrinth.setHorizontalAlignment(SwingConstants.LEFT);
		discoverLabyrinth.setToolTipText("Discover labyrinth");
		discoverLabyrinth.setBorder(BorderFactory.createEmptyBorder());
		discoverLabyrinth.setContentAreaFilled(false);
		discoverLabyrinth.setCursor(new Cursor(Cursor.HAND_CURSOR));
		discoverLabyrinth.setBounds(10, 354, 33, 33);
		controlPanel.add(discoverLabyrinth);
		
		JButton btnStop = new JButton("Stop");
		btnStop.setBounds(74, 356, 55, 23);
		controlPanel.add(btnStop);
		btnStop.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				robotControl.setDiscover(false);
			}
		});
		discoverLabyrinth.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				robotControl.setDiscover(true);
			}
		});
		btnNewButton_1.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				JFileChooser fc = new JFileChooser();
				int returnVal = fc.showOpenDialog(null);
				 
	            if (returnVal == JFileChooser.APPROVE_OPTION) {
	                File file = fc.getSelectedFile();
	                try {
						Labyrinth labyrinth = LabyrinthParser.parse(file);
						robotControl.getSimulator().setLabyrinth(labyrinth);
					} catch (IOException e1) {
						// TODO Auto-generated catch block
						e1.printStackTrace();
					} 	               
	            }	
			}
		});
		
		JPanel panel_1 = new JPanel();
		panel_1.setBorder(new TitledBorder(null, "Simulator", TitledBorder.LEADING, TitledBorder.TOP, null, null));
		panel_1.setBounds(678, 3, 168, 203);
		panel.add(panel_1);
		panel_1.setLayout(null);
		
		JLabel lblTurnSonar = new JLabel("Turn sonar");
		lblTurnSonar.setBounds(16, 32, 86, 14);
		panel_1.add(lblTurnSonar);
		lblTurnSonar.setFont(new Font("Tahoma", Font.PLAIN, 12));
		
		sonar_up = new JButton("^");
		sonar_up.setBounds(91, 30, 42, 20);
		panel_1.add(sonar_up);
		sonar_up.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				robotControl.setDesiredSonarAngle(0);
			}
		});
		sonar_up.setFont(new Font("Tahoma", Font.BOLD, 11));
		
		sonar_left = new JButton("<");
		sonar_left.setBounds(66, 50, 42, 20);
		panel_1.add(sonar_left);
		sonar_left.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				robotControl.setDesiredSonarAngle(-90);
			}
		});
		sonar_left.setFont(new Font("Tahoma", Font.BOLD, 11));
		
		sonar_right = new JButton(">");
		sonar_right.setBounds(116, 50, 42, 20);
		panel_1.add(sonar_right);
		sonar_right.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				robotControl.setDesiredSonarAngle(90);
			}
		});
		sonar_right.setFont(new Font("Tahoma", Font.BOLD, 11));
		
		JLabel lblX = new JLabel("x");
		lblX.setBounds(16, 84, 16, 14);
		panel_1.add(lblX);
		lblX.setHorizontalAlignment(SwingConstants.CENTER);
		
		setX = new JTextField();
		setX.setBounds(41, 81, 40, 20);
		panel_1.add(setX);
		setX.setColumns(10);
		
		JLabel lblY = new JLabel("y");
		lblY.setBounds(13, 109, 16, 14);
		panel_1.add(lblY);
		lblY.setHorizontalAlignment(SwingConstants.CENTER);
		
		setY = new JTextField();
		setY.setBounds(41, 106, 40, 20);
		panel_1.add(setY);
		setY.setColumns(10);
		
		JLabel lblAngle = new JLabel("angle");
		lblAngle.setBounds(87, 98, 46, 14);
		panel_1.add(lblAngle);
		
		setAngle = new JTextField();
		setAngle.setBounds(118, 95, 40, 20);
		panel_1.add(setAngle);
		setAngle.setColumns(10);
		
		JButton btnSetPosition = new JButton("Set position");
		btnSetPosition.setBounds(23, 137, 88, 23);
		panel_1.add(btnSetPosition);
		
		JLabel lblNoise = new JLabel("Noise");
		lblNoise.setFont(new Font("Tahoma", Font.PLAIN, 12));
		lblNoise.setBounds(10, 174, 46, 14);
		panel_1.add(lblNoise);
		
		JButton btnNoise = new JButton("Enable");
		btnNoise.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent event) {
				JButton source = (JButton) event.getSource();
				
				if (source.getText().equals("Enable")) {
					robotControl.getSimulator().setRuis(true);
					source.setText("Disable");
				} else {
					robotControl.getSimulator().setRuis(false);
					source.setText("Enable");
				}
			}
		});
		btnNoise.setBounds(55, 171, 89, 23);
		panel_1.add(btnNoise);
		
		JPanel panel_2 = new JPanel();
		panel_2.setBorder(new TitledBorder(null, "Calibratie", TitledBorder.LEADING, TitledBorder.TOP, null, null));
		panel_2.setBounds(698, 226, 148, 130);
		panel.add(panel_2);
		
		JButton btnCalibrateBlack = new JButton("Set black");
		btnCalibrateBlack.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				robotControl.setColorToCalibrate(SensorColour.BLACK);
				robotControl.setColorCalibration(true);
			}
		});
		panel_2.add(btnCalibrateBlack);
		
		JButton btnCalibrateWhite = new JButton("Set white");
		btnCalibrateWhite.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				robotControl.setColorToCalibrate(SensorColour.WHITE);
				robotControl.setColorCalibration(true);
			}
		});
		panel_2.add(btnCalibrateWhite);
		
		JButton btnCalibrateBrown = new JButton("Set brown");
		btnCalibrateBrown.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				robotControl.setColorToCalibrate(SensorColour.BROWN);
				robotControl.setColorCalibration(true);
			}
		});
		panel_2.add(btnCalibrateBrown);
		btnSetPosition.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				double x = 0;
				double y = 0;
				double angle = 0;
				boolean posCorrect = false;
				boolean angleCorrect = false;
				setX.setBackground(Color.white);
				setY.setBackground(Color.white);
				setAngle.setBackground(Color.white);
				
				if (!setX.getText().equals("") || !setY.equals("")) {
					try {
						x = Double.parseDouble(setX.getText());
						y = Double.parseDouble(setY.getText());
					} catch (NumberFormatException ex) {
						setX.setBackground(Color.red);
						setY.setBackground(Color.red);
					}
					
					posCorrect = true;
				}
				
				if (setAngle.getText() != "") {
					try {
						angle = Double.parseDouble(setAngle.getText());
					} catch (NumberFormatException ex) {
						setAngle.setBackground(Color.red);
					}
					
					angleCorrect = true;
				}
				
				Simulator sim = robotControl.getSimulator();
				x = (posCorrect) ? x : sim.getPosition().getX();
				y = (posCorrect) ? y : sim.getPosition().getY();
				angle = (angleCorrect) ? angle : sim.getPosition().getOrientation();
				
				sim.setPosition(x, y, angle);
			}
		});

		JRadioButton rdbtnArrows = new JRadioButton("Arrows");
		rdbtnArrows.setBounds(6, 7, 59, 23);
		rdbtnArrows.setSelected(true);
		remoteControl.add(rdbtnArrows);
		rdbtnArrows.addActionListener(radioButtonListener);
		
		btnRobotUp = new JButton("^");
		btnRobotUp.addMouseListener(new MouseAdapter() {
			@Override
			public void mousePressed(MouseEvent arg0) {
				robotControl.setDriveDirection(RobotDirection.FORWARD);
			}
			
			@Override
			public void mouseReleased(MouseEvent e) {
				robotControl.setDriveDirection(RobotDirection.NONE);
			}
		});
		btnRobotUp.setFont(new Font("Tahoma", Font.PLAIN, 14));
		btnRobotUp.setBounds(127, 25, 42, 20);
		remoteControl.add(btnRobotUp);
		
		btnRobotLeft = new JButton("<");
		btnRobotLeft.addMouseListener(new MouseAdapter() {
			@Override
			public void mousePressed(MouseEvent arg0) {
				robotControl.setDriveDirection(RobotDirection.LEFT);
			}
			
			@Override
			public void mouseReleased(MouseEvent e) {
				robotControl.setDriveDirection(RobotDirection.NONE);
			}
		});
		btnRobotLeft.setFont(new Font("Tahoma", Font.PLAIN, 11));
		btnRobotLeft.setBounds(96, 45, 42, 20);
		remoteControl.add(btnRobotLeft);
		
		btnRobotRight = new JButton(">");
		btnRobotRight.addMouseListener(new MouseAdapter() {
			@Override
			public void mousePressed(MouseEvent arg0) {
				robotControl.setDriveDirection(RobotDirection.RIGHT);
			}
			
			@Override
			public void mouseReleased(MouseEvent e) {
				robotControl.setDriveDirection(RobotDirection.NONE);
			}
		});
		btnRobotRight.setFont(new Font("Tahoma", Font.PLAIN, 11));
		btnRobotRight.setBounds(156, 45, 42, 20);
		remoteControl.add(btnRobotRight);
		
		btnRobotDown = new JButton("^");
		btnRobotDown.setHorizontalAlignment(SwingConstants.TRAILING);
		btnRobotDown.addMouseListener(new MouseAdapter() {
			@Override
			public void mousePressed(MouseEvent arg0) {
				robotControl.setDriveDirection(RobotDirection.BACKWARD);
			}
			
			@Override
			public void mouseReleased(MouseEvent e) {
				robotControl.setDriveDirection(RobotDirection.NONE);
			}
		});
		btnRobotDown.setFont(new Font("Tahoma", Font.BOLD, 12));
		btnRobotDown.setBounds(127, 65, 42, 20);
		remoteControl.add(btnRobotDown);
		AffineTransform angle =  java.awt.geom.AffineTransform.getRotateInstance(Math.PI);
		btnRobotDown.setFont(btnRobotDown.getFont().deriveFont(angle));

		((KeyDispatcher) keyDispatcher).setUp(btnRobotUp);
		((KeyDispatcher) keyDispatcher).setLeft(btnRobotLeft);
		((KeyDispatcher) keyDispatcher).setDown(btnRobotDown);
		((KeyDispatcher) keyDispatcher).setRight(btnRobotRight);

		JRadioButton rdbtnPrecise = new JRadioButton("");
		rdbtnPrecise.setBounds(6, 105, 21, 21);
		remoteControl.add(rdbtnPrecise);
		rdbtnPrecise.addActionListener(radioButtonListener);
		
		ButtonGroup remoteControls = new ButtonGroup();
		remoteControls.add(rdbtnArrows);
		remoteControls.add(rdbtnPrecise);
		
		travelDistance = new JTextField();
		travelDistance.setBounds(33, 105, 42, 20);
		remoteControl.add(travelDistance);
		travelDistance.setColumns(10);
		
		btnTravel = new JButton("Travel");
		btnTravel.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				if (travelDistance.getText() != "") {
					try {
						double distance = Double.parseDouble(travelDistance.getText());
							robotControl.setTravelDistance(distance);
							travelDistance.setBackground(Color.white);
					} catch (NumberFormatException ex) {
						travelDistance.setBackground(Color.red);
					}
				}
			}
		});
		btnTravel.setBounds(85, 105, 73, 23);
		remoteControl.add(btnTravel);
		
		btnRotate = new JButton("Rotate");
		btnRotate.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				if (rotateAngle.getText() != "") {
					try {
						double angle = Double.parseDouble(rotateAngle.getText());
							robotControl.setRotateAngle(angle);
							rotateAngle.setBackground(Color.white);
					} catch (NumberFormatException ex) {
						rotateAngle.setBackground(Color.red);
					}
				}
			}
		});
		
		btnTravel20 = new JButton("" + TRAVEL_VALUE);
		btnTravel20.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				robotControl.setTravelDistance(TRAVEL_VALUE);
			}
		});
		btnTravel20.setBounds(96, 130, 65, 23);
		remoteControl.add(btnTravel20);
		
		btnTravel20Back = new JButton("- 40");
		btnTravel20Back.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				robotControl.setTravelDistance(-TRAVEL_VALUE);
			}
		});
		btnTravel20Back.setBounds(168, 130, 65, 23);
		remoteControl.add(btnTravel20Back);
		
		rotateAngle = new JTextField();
		rotateAngle.setColumns(10);
		rotateAngle.setBounds(33, 160, 42, 20);
		remoteControl.add(rotateAngle);
		btnRotate.setBounds(85, 160, 73, 23);
		remoteControl.add(btnRotate);
		
		btnRotate90 = new JButton("Right");
		btnRotate90.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				robotControl.setRotateAngle(ROTATE_VALUE);
			}
		});
		btnRotate90.setBounds(168, 185, 65, 23);
		remoteControl.add(btnRotate90);
		
		btnRotateMin90 = new JButton("Left");
		btnRotateMin90.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				robotControl.setRotateAngle(-ROTATE_VALUE);
			}
		});
		btnRotateMin90.setBounds(96, 185, 65, 23);
		remoteControl.add(btnRotateMin90);
		
		JButton btnGoToMiddle = new JButton("Go to middle");
		btnGoToMiddle.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				robotControl.setGoToMiddle(true);
			}
		});
		btnGoToMiddle.setBounds(33, 219, 105, 23);
		remoteControl.add(btnGoToMiddle);
		
		rdbtnArrows.doClick();
	}
	
	private class RadioButtonListener implements ActionListener
	{

		@Override
		public void actionPerformed(ActionEvent e) {
			String action = e.getActionCommand();
			if(action.equals("Arrows")) {
				((KeyDispatcher)keyDispatcher).setEnabled(true);

				btnRobotUp.setEnabled(true);
				btnRobotLeft.setEnabled(true);
				btnRobotRight.setEnabled(true);
				btnRobotDown.setEnabled(true);

				travelDistance.setEnabled(false);
				rotateAngle.setEnabled(false);
				btnTravel.setEnabled(false);
				btnTravel20.setEnabled(false);
				btnTravel20Back.setEnabled(false);
				btnRotate.setEnabled(false);
				btnRotate90.setEnabled(false);
				btnRotateMin90.setEnabled(false);
			}
			if(action.equals("")) {
				((KeyDispatcher)keyDispatcher).setEnabled(false);
				
				btnRobotUp.setEnabled(false);
				btnRobotLeft.setEnabled(false);
				btnRobotRight.setEnabled(false);
				btnRobotDown.setEnabled(false);

				travelDistance.setEnabled(true);
				rotateAngle.setEnabled(true);
				btnTravel.setEnabled(true);
				btnTravel20.setEnabled(true);
				btnTravel20Back.setEnabled(true);
				btnRotate.setEnabled(true);
				btnRotate90.setEnabled(true);
				btnRotateMin90.setEnabled(true);
			}
		}
		
	}
	
	public void setRobotDirection(RobotDirection direction) {
		if (direction == null)
			direction = RobotDirection.NONE;
		
		lblRobotDirectionEdit.setText(direction.toString());
	}
	
	public void setSensorAngle(double angle) {
		lblSonarAngleEdit.setText(Double.toString(angle % 360));
	}
	
	public void setLightValue(int value) {
		lblLightSensorEdit.setText(Integer.toString(value));
	}
	
	public void setLightColour(SensorColour colour) {
		lblLightSensorColour.setText(colour.toString());
	}
	
	public void setSonarDistance(int distance) {
		lblSonarEdit.setText(Integer.toString(distance));
		if (distance < 40) {
			double factor = distance / 40d;
			int newRed = (int) (255 - ((255 - GREEN.getRed()) * factor));
			int newGreen = (int) (0 + (GREEN.getGreen() * factor));
			int newBlue = (int) (0 + (GREEN.getBlue() * factor));
			lblSonarEdit.setForeground(new Color(newRed, newGreen, newBlue));
			if (distance < 30)
				lblSonarEdit.setFont(lblSonarEdit.getFont().deriveFont(Font.BOLD));
			else
				lblSonarEdit.setFont(lblSonarEdit.getFont().deriveFont(Font.PLAIN));
		} else
			lblSonarEdit.setForeground(GREEN);
	}
	
	public void setTouchLeft(boolean isOn){
		if(isOn){
			lblTouch_1Edit.setText("On");
			lblTouch_1Edit.setForeground(GREEN);
		}
		else{
			lblTouch_1Edit.setText("Off");
			lblTouch_1Edit.setForeground(Color.RED);
		}
	}
	
	public void setTouchRight(boolean isOn){
		if(isOn){
			lblTouch_2Edit.setText("On");
			lblTouch_2Edit.setForeground(GREEN);
		}
		else{
			lblTouch_2Edit.setText("Off");
			lblTouch_2Edit.setForeground(Color.RED);
		}
	}
	
	public void setPilot(String pilot) {
		lblPilot.setText(pilot);
	}
	
	
	
	public void updateSonarArrow(int angle) {
		JButton[] sonar = {sonar_up, sonar_left, sonar_right};
		for (JButton button: sonar) {
			button.setBackground(new Color(240, 240, 240));
		}
		if (angle == 0)
			sonar_up.setBackground(GREEN);
		else if (angle == 90)
			sonar_right.setBackground(GREEN);
		else if (angle == -90)
			sonar_left.setBackground(GREEN);
	}
	
	public void updatePose(Pose pose) {
		if (pose != null) {
			lblRobotOrientationEdit.setText("" + (int)pose.getHeading() );
			lblRobotPositionEdit.setText("(" + Math.round(pose.getX()) + ", " + Math.round(pose.getY()) + ")");
		} else {
			lblRobotOrientationEdit.setText("None");
			lblRobotPositionEdit.setText("None");
		}
	}

	private boolean first = true;
	private boolean firstDebug = true;
	private JTextField travelDistance;
	private JTextField rotateAngle;
	private JTextField setX;
	private JTextField setY;
	private JTextField setAngle;
	
	public void addAction(String text) {
		if (first) {
			textAreaActie.append(text);
			first = false;
		}
		else
			textAreaActie.append("\n" + text);
		
		textAreaActie.setCaretPosition(textAreaActie.getDocument().getLength());
	}
	
	public void addDebug(String text) {
		if (firstDebug) {
			textAreaDebug.append(text);
			firstDebug = false;
		}
		else
			textAreaDebug.append("\n" + text);
		
		textAreaDebug.setCaretPosition(textAreaDebug.getDocument().getLength());
	}

	@Override
	public void handleTravelSpeedChange(double speed) {
		this.speed.setText(Double.toString(speed));
	}

	@Override
	public void handleRotateSpeedChange(double speed) {
		rotate.setText(Double.toString(speed));		
	}
}
